package com.hliushi.demo.repository;

import com.hliushi.demo.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 接口JapRepository 是 接口CrudRepository的子类
 * 他们都是需要填写两个泛型, 前者为你想操作的类 (需要@Entity进行标注)
 * 后者为主键的类型, 此处由于我们想操作User类, 且它的主键为Integer, 所以此处填写UserEntity, Integer
 * #
 * JpaSpecificationExecutor: 此处为高级的查询功能, 要填写想操作的类(需要@Entity进行标注)
 *
 * @author llhuang10
 */
public interface UserEntityRepository extends CrudRepository<UserEntity, Integer>, JpaSpecificationExecutor<UserEntity> {


    // 多条件查询的命名规则
    // findBy + 属性名称 + "查询方式" + "多条件的连接符(and | or)" + 属性名称 + 查询方式
    List<UserEntity> findByEmailLikeAndNameLike(String email, String name);

    // 根据命名规则进行查询
    // findOneBy 和 findBy效果相同, 因为此处没有使用like ??
    // 推荐使用findOneBy的写法, 一面产生歧义
    UserEntity findByEmail(String email);

    UserEntity findOneByEmail(String email);

    // 根据命名规则模糊查询
    // find + by + 属性名称 + like | isnull
    // 此处的email应该为 = "%xxx%", 对于like 需要自定添加 %
    List<UserEntity> findByEmailLike(String email);

    /**
     * Jpql
     * Jpql 的语法与 sql 几乎一直
     * 不一样的是, SQL需要标注表明等信息, Jpql则使用类名代替表名
     * 如果不写select而是直接使用from子句, 表明获取对象的全部属性
     * #
     * Jpql写在继承了CurdRepository, JpaSpecificationExecutor的接口中
     */

    // 此处的 ? 为占位符, ?1 表示第一个参数
    @Query(value = "from UserEntity where id = ?1")
    UserEntity findUserEntityByIdJpql(Integer id);

    // : 同为占位符, 后面可根参数名 (推荐使用此方法)
    @Query(value = "from UserEntity where id = :iId")
    UserEntity findUserEntityByIdJpql2(Integer iId);


    /**
     * 更新操作
     */
    @Modifying          // 为更新操作
    @Transactional      // 标注此方法为事务, 更新删除查找需要此注解
    @Query(value = "update UserEntity set email = :email where  id = :id")
    Integer updateUserEntityByJpql(String email, Integer id);


    /**
     * 可以使用@Param给参数去别名, 并用在jpql \ 原生sql中
     */
    @Query(value = "select * from user where lower(user.id) = :id", nativeQuery = true)
    UserEntity userEntityQueryFindById(@Param("id") Integer integerId);

    @Query(value = "select new map(u.id as id, u.name as name) from UserEntity u where u.email like  :email")
    List<Object> findByLikeEmailGetIdAndName(String email);

    boolean findByAccount(String account);


    boolean findByAccountAndPassword(String account, String password);
}
